﻿using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Threading.Tasks;


namespace GetMM
{
    class Program
    {
        static WebClient wc = new WebClient();
        static string url = @"http://jandan.net/ooxx/";
        static string downPath = Environment.CurrentDirectory + "\\download\\";
        static BlockingCollection<string> imgQueue = new BlockingCollection<string>(100);//存入待下载的img地址

        //仍有不少问题  1下载图片大小为0   2内存泄露
        static void Main(string[] args)
        {
            //设置一下允许执行的线程数量
            ThreadPool.SetMaxThreads(100, 50);

            wc.Headers.Add("Accept-Language", "zh-cn");
            wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0");

            PictureBox pb = new PictureBox();

            wc.Encoding = Encoding.UTF8;
            string str = wc.DownloadString(url);

            string s = @"current-comment-page\D+(\d+)\D+span";
            Regex reg = new Regex(s, RegexOptions.IgnoreCase);
            string num = reg.Match(str).Groups[1].Value;

            int pagNum;
            int.TryParse(num, out pagNum);

            #region 检查图片是否正确
            ThreadPool.QueueUserWorkItem(checkImg =>
            {
                CheckImg(downPath);
            });
            #endregion

            #region 取图片的下载地址
            ThreadPool.QueueUserWorkItem(getImgUrl =>
            {
                Parallel.For(1, pagNum, i =>
                {
                    GetImgUrl(url + "page-" + (pagNum - i + 1));
                });
            });
            #endregion

            #region 下载图片
            if (!Directory.Exists(downPath)) Directory.CreateDirectory(downPath);

            ThreadPool.QueueUserWorkItem(downloadImg =>
            {
                while (!imgQueue.IsCompleted)
                {
                    string imgUrl = imgQueue.Take();

                    string eName = imgUrl.Substring(imgUrl.LastIndexOf("."));

                    //过滤掉一下杂质,比如说广告
                    if (!string.IsNullOrEmpty(eName) && imgUrl.Contains("sinaimg"))
                    {
                            string path = downPath + GenerateFileName(imgUrl, eName);
                        //download: if (!File.Exists(path))
                        if (!File.Exists(path))
                        {
                            ThreadPool.QueueUserWorkItem(down =>
                            {
                                try
                                {
                                    //改造了此处，这样就可以判断异步下载是否完成了
                                    using (WebClient wcDown = new WebClient())
                                    {
                                        wcDown.Headers.Add("Accept-Language", "zh-cn");
                                        wcDown.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0");
                                        wcDown.DownloadFileAsync(new Uri(imgUrl), path);
                                    }

                                    Debug.WriteLine("下载完成: " + imgUrl);

                                }
                                catch (Exception)
                                {
                                    try
                                    {
                                        File.Delete(path);
                                    }
                                    catch { }
                                }
                            });
                        }
                    }
                }
            });
            #endregion

            Console.ReadKey();
        }

        /// <summary>
        /// 获取图片的下载地址
        /// </summary>
        /// <param name="url"></param>
        private static void GetImgUrl(string url)
        {
            try
            {
                using (WebClient wcDown = new WebClient())
                {
                    wcDown.Headers.Add("Accept-Language", "zh-cn");
                    wcDown.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0");
                    wcDown.Encoding = Encoding.UTF8;
                    Regex reg = new Regex(@"src=""(http://.*?[^s])""", RegexOptions.IgnoreCase);
                    string htmlString = wcDown.DownloadString(new Uri(url));
                    foreach (Match item in reg.Matches(htmlString))
                    {
                        string pStr = item.Value;
                        if (pStr.Length - pStr.LastIndexOf(".") == 5)
                        {
                            string imgUrl = item.Groups[1].Value;
                            if (!string.IsNullOrEmpty(imgUrl))
                            {
                                imgQueue.Add(imgUrl);
                            }
                        }
                    }
                }
                //调用垃圾回收,强制回收垃圾
                //System.GC.Collect();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

        /// <summary>
        /// 检查图片是否正确,不正确 , 删除
        /// </summary>
        /// <param name="path"></param>
        private static void CheckImg(string path)
        {
            DirectoryInfo di = new DirectoryInfo(path);
            if (di.Exists)
            {
                PictureBox pb = new PictureBox();
                FileInfo[] fis = di.GetFiles();
                foreach (FileInfo fi in fis)
                {
                    try
                    {
                        if (fi.Length == 0)
                        {
                            throw new Exception("图片大小为空");
                        }
                        else
                        {
                            pb.Load(fi.FullName);
                        }
                    }
                    catch (Exception)
                    {
                        pb.Dispose();
                        try
                        {
                            fi.Delete();
                            Debug.WriteLine("删除不正常文件 " + fi.Name);
                        }
                        catch { }
                    }
                }
            }
            GC.Collect();
        }

        /// <summary>
        /// 生成图片的文件名
        /// </summary>
        /// <param name="url"></param>
        /// <param name="eName"></param>
        /// <returns></returns>
        private static string GenerateFileName(string url, string eName)
        {
            return url.Replace(@"/", "").Replace(":", "").Replace(eName, "").Replace(".", "") + eName;
        }
    }
}